﻿Partial Public Class LogPage

    Private m_log As Boolean = True
    Private m_update_frequently As Boolean = False

#Region " properties "
    Public Property Log() As Boolean
        Get
            Return m_log
        End Get
        Set(ByVal value As Boolean)
            If m_log = value Then Return
            m_log = True
            If value Then
                WriteLine("logging turned on")
            Else
                WriteLine("logging turned off")
            End If
            m_log = value
            lbxLog.IsEnabled = m_log
        End Set
    End Property
    Public WriteOnly Property UpdateFrequently() As Boolean
        Set(ByVal value As Boolean)
            m_update_frequently = value
        End Set
    End Property
#End Region

    Private Delegate Sub DlgWriteline(ByVal message As String)
    Public Sub WriteLine(ByVal message As String)

        If Not m_log Then Return

        ' Trace: False - album: 193d7d80-93fa-4e23-8f9f-3fa0fc2ac6cc | North of 47Â° | SELECT * FROM dbo.Photo WHERE Location.Lat > 47
        ' LogPage.Writeline: False - on thread:  - album: 193d7d80-93fa-4e23-8f9f-3fa0fc2ac6cc | North of 47Â° | SELECT * FROM dbo.Photo WHERE Location.Lat > 47
        ' Trace: False - ... read 15 album(s)
        ' LogPage.Writeline: False - on thread:  - ... read 15 album(s)
        ' ---- okay until here, need to call Dispatcher.Invoke -----------------
        ' Trace: False - loading photos for album 'All Photos' ...
        ' LogPage.Writeline: False - before Dispatcher.Invoke in LogPage.WriteLine: loading photos for album 'All Photos' ...
        ' LogPage.Writeline: False - on thread: LoadAlbumThread want thread: MyMainThread
        ' LogPage.Writeline: False - thread state: Running
        ' Trace: False - loading query results into DataTable from table State
        ' ---- app freezes here until taskbar context menu used ----------------
        ' LogPage.Writeline: False - on thread: MyMainThread - loading photos for album 'All Photos' ...
        ' LogPage.Writeline: False - after Dispatcher.Invoke in LogPage.WriteLine: loading photos for album 'All Photos' ...
        ' SqlEvent: False - command - get column names: Photo
        ' Trace (LogListener): False - 	SQL: get column names: Photo: SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.Columns where TABLE_NAME = 'Photo'
        ' 


        If Not Dispatcher.CheckAccess() Then
            Throw New ApplicationException("LogPage.WriteLine called from wrong thread.")
            ' BUG: In unknown circumstances, this will cause the Main Thread to block, freezing the application
            ' The top frame of the stack trace shows [In sleep, wait or join]
            ' This cannot be reproduced in the debugger: run without debugging and when the app freezes,
            ' attach to it with the debugger and pause execution.
            g_coreevent_handler.Write("LogPage.Writeline", "before Dispatcher.Invoke in LogPage.WriteLine: " & message)
            g_coreevent_handler.Write("LogPage.Writeline", "on thread: " & System.Threading.Thread.CurrentThread.Name & " want thread: " & Dispatcher.Thread.Name)
            g_coreevent_handler.Write("LogPage.Writeline", "thread state: " & [Enum].GetName(Dispatcher.Thread.ThreadState.GetType(), Dispatcher.Thread.ThreadState))
            Dispatcher.Invoke(Windows.Threading.DispatcherPriority.Send, New DlgWriteline(AddressOf WriteLine), message)
            g_coreevent_handler.Write("LogPage.Writeline", "after Dispatcher.Invoke in LogPage.WriteLine: " & message)
        Else
            'g_coreevent_handler.Write("LogPage.Writeline", "on thread: " & System.Threading.Thread.CurrentThread.Name & " - " & message)
            If message.Length > 300 Then message = message.Substring(0, 299) & " (truncated...)"

            Dim lmsg As String = message.ToLower
            Dim berror As Boolean = lmsg.StartsWith("exception") Or lmsg.StartsWith("sqlexception") Or _
                                    lmsg.StartsWith("assert") Or lmsg.StartsWith("error")
            Dim lvi As New ListViewItem()
            If berror Then
                g_mainpage.SetStatusbarError(message)
                message = "******* " & message
                Dim text As New Label
                text.Content = message
                text.Background = System.Windows.Media.Brushes.Red
                lvi.Content = text
            Else
                lvi.Content = message
            End If
            lbxLog.Items.Add(lvi)
            lbxLog.SelectedItem = lvi
            lbxLog.BringIntoView()
        End If
    End Sub

    Private Sub btnClear_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClear.Click
        lbxLog.Items.Clear()
    End Sub

    Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim d As New System.Windows.Forms.SaveFileDialog
        d.CheckPathExists = True
        d.DefaultExt = ".log"
        d.AddExtension = True
        d.Filter = "Log files (*.log)|*.log"
        d.RestoreDirectory = True
        Dim rc As System.Windows.Forms.DialogResult = d.ShowDialog()
        If rc = System.Windows.Forms.DialogResult.OK Then SaveLog(d.FileName)
    End Sub

    Private Sub SaveLog(ByVal fname As String)
        Dim ostr As New IO.StreamWriter(fname, False)
        For Each item As Object In lbxLog.Items
            ostr.WriteLine(item.Content.ToString())
        Next
        ostr.Close()
        MessageBox.Show("Saved log to file " & fname)
    End Sub

    Private m_thr As System.Threading.Thread = Nothing

    Private Sub btnTest_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnTest.Click
        If m_thr Is Nothing Then
            btnTest.Content = "Stop Test"
            m_thr = New System.Threading.Thread(AddressOf SpinTestLog)
            m_thr.Name = "SpinTestLog thread"
            m_thr.Start()
        Else
            m_thr.Abort()
            m_thr = Nothing
            btnTest.Content = "Test"
        End If
    End Sub

    Private Sub SpinTestLog()
        Static i As Integer = 0
        While True
            i += 1
            Trace.WriteLine(i)
            System.Threading.Thread.Sleep(500)
        End While
    End Sub

    Private Sub LogPage_IsVisibleChanged(ByVal sender As Object, ByVal e As System.Windows.DependencyPropertyChangedEventArgs) Handles Me.IsVisibleChanged
        If IsVisible Then
            g_mainpage.ClearStatusbar()
        End If
    End Sub
End Class
